<?php
/**
 * HTTP客户端接口模块
 * 
 * @author jlpay-sdk-php
 * @version 1.0.0
 */

namespace JLPay\Core\Http;

use JLPay\Core\OrgConfig;

/**
 * HTTP客户端接口
 */
interface HttpClient
{
    /**
     * 执行HTTP请求
     * 
     * @param HttpRequest $request HttpRequest对象
     * @return HttpResponse HttpResponse对象
     * @throws HttpExecutionException 执行异常
     * @throws HttpStatusCodeException 状态码异常
     */
    public function execute(HttpRequest $request);
}

/**
 * 默认HTTP客户端实现类
 */
class DefaultHttpClient implements HttpClient
{
    private OrgConfig $config;

    public function __construct(OrgConfig $config)
    {
        $this->config = $config;
    }

    /**
     * 执行HTTP请求
     *
     * @param HttpRequest $request
     * @return HttpResponse
     */
    public function execute(HttpRequest $request): HttpResponse
    {
        // 这里是一个简化的实现，实际项目中需要使用真正的HTTP客户端
        // 比如 Guzzle 或者 cURL
        
        $url = $request->getUrl();
        $method = $request->getMethod();
        $headers = $request->getHeaders();
        $body = $request->getBody();

        // 构建cURL请求
        $ch = curl_init();
        
        curl_setopt_array($ch, [
            CURLOPT_URL => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_CUSTOMREQUEST => $method,
            CURLOPT_TIMEOUT => $this->config->getReadTimeout() ?? 30,
            CURLOPT_CONNECTTIMEOUT => $this->config->getConnectTimeout() ?? 10,
            CURLOPT_HEADER => true,
            CURLOPT_NOBODY => false,
        ]);

        // 设置请求头
        if (!empty($headers)) {
            $headerArray = [];
            foreach ($headers as $key => $value) {
                $headerArray[] = $key . ': ' . $value;
            }
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headerArray);
        }

        // 设置请求体
        if (!empty($body) && in_array($method, ['POST', 'PUT', 'PATCH'])) {
            if (is_array($body)) {
                curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));
            } else {
                curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
            }
        }

        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
        
        if ($response === false) {
            $error = curl_error($ch);
            curl_close($ch);
            throw new \Exception("HTTP请求失败: " . $error);
        }

        curl_close($ch);

        // 分离响应头和响应体
        $responseHeaders = substr($response, 0, $headerSize);
        $responseBody = substr($response, $headerSize);

        // 解析响应头
        $parsedHeaders = $this->parseHeaders($responseHeaders);

        $response = new HttpResponse();
        $response->status = $httpCode;
        $response->headers = $parsedHeaders;
        $response->body = $responseBody;
        return $response;
    }

    /**
     * 解析响应头
     *
     * @param string $headerString
     * @return array
     */
    private function parseHeaders(string $headerString): array
    {
        $headers = [];
        $lines = explode("\r\n", $headerString);
        
        foreach ($lines as $line) {
            if (strpos($line, ':') !== false) {
                list($key, $value) = explode(':', $line, 2);
                $headers[trim($key)] = trim($value);
            }
        }
        
        return $headers;
    }
}

 